﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace System.Data.SQLiteProvider
{
    public class SQLiteConfigService
    {
        const string sqliteConfigPath = "~/sqlite.config";

        System.Xml.XmlDocument xml;

        public System.Data.SQLite.SQLiteConnectionStringBuilder ConnectionStringBuilder { get; set; }

        public string DbFilePhyPath { get; set; }

        public bool IsExistDb { get; set; }

        public SQLiteConfigService()
        {
            xml = new Xml.XmlDocument();
            try
            {
                var configPath = AppDomain.CurrentDomain.BaseDirectory;
                if (sqliteConfigPath.StartsWith("~/"))
                {
                    configPath = configPath + sqliteConfigPath.Replace("~/", "");
                }
                xml.Load(configPath);
            }
            catch (Exception ex)
            {
                throw new Exception(ex.InnerException != null ? ex.InnerException.Message : ex.Message);
            }
            this.ConnectionStringBuilder = new System.Data.SQLite.SQLiteConnectionStringBuilder();
            if (!string.IsNullOrEmpty(this.GetDataSource()))
            {
                var path = this.GetDataSource();
                if (System.IO.File.Exists(path))
                {
                    this.IsExistDb = true;
                }
                this.DbFilePhyPath = path;
                this.ConnectionStringBuilder.DataSource = path;
            }
            else
            {
                throw new Exception("sqlite config datasource error");
            }
            if (this.GetCacheSize() > 0)
            {
                this.ConnectionStringBuilder.CacheSize = this.GetCacheSize();
            }
            if (this.GetDefaultTimeout() > 0)
            {
                this.ConnectionStringBuilder.DefaultTimeout = this.GetDefaultTimeout();
            }
            if(this.GetFailIfMissing())
            {
                this.ConnectionStringBuilder.FailIfMissing = this.GetFailIfMissing();
            }
            if (this.GetMaxPageCount() > 0)
            {
                this.ConnectionStringBuilder.MaxPageCount = this.GetMaxPageCount();
            }
            if (this.GetPageSize() > 0)
            {
                this.ConnectionStringBuilder.PageSize = this.GetPageSize();
            }
            if (!string.IsNullOrEmpty(this.GetPwd()))
            {
                this.ConnectionStringBuilder.Password = this.GetPwd();
            }
            if (this.GetPooling())
            {
                this.ConnectionStringBuilder.Pooling = this.GetPooling();
            }
            if (this.GetUseUTF16Encoding())
            {
                this.ConnectionStringBuilder.UseUTF16Encoding = this.GetUseUTF16Encoding();
            }
            if (this.GetVersion() > 0)
            {
                this.ConnectionStringBuilder.Version = this.GetVersion();
            }
        }

        protected int GetCacheSize()
        {
            var path = "/configuration/sqlite/dbconfig/cachesize";
            var res = -1;
            var node = xml.SelectSingleNode(path);
            if (node != null)
            {
                var temp = node.Value;
                if (!string.IsNullOrEmpty(temp))
                {
                    int.TryParse(temp, out res);
                }
            }
            return res;
        }

        protected string GetDataSource()
        {
            var path = "/configuration/sqlite/dbconfig/datasource";
            var res = "";
            var node = xml.SelectSingleNode(path);
            if (node != null)
            {
                var temp = node.InnerText;
                if (!string.IsNullOrEmpty(temp) && temp.StartsWith("~/"))
                {
                    res = AppDomain.CurrentDomain.BaseDirectory + temp.Replace("~/", "");
                }
                else if (!string.IsNullOrEmpty(temp) && temp.StartsWith("/"))
                {
                    res = AppDomain.CurrentDomain.BaseDirectory + temp.Substring(1, temp.Length - 1);
                }
                else
                {
                    res = temp;
                }
            }
            return res;
        }

        protected int GetDefaultTimeout()
        {
            var path = "/configuration/sqlite/dbconfig/defaulttimeout";
            var res = -1;
            var node = xml.SelectSingleNode(path);
            if (node != null)
            {
                var temp = node.Value;
                if (!string.IsNullOrEmpty(temp))
                {
                    int.TryParse(temp, out res);
                }
            }
            return res;
        }

        protected bool GetFailIfMissing()
        {
            var path = "/configuration/sqlite/dbconfig/failifmissing";
            var res = false;
            var node = xml.SelectSingleNode(path);
            if (node != null)
            {
                var temp = node.Value;
                if (!string.IsNullOrEmpty(temp) && temp.ToLower().CompareTo("true") == 0)
                {
                    res = true;
                }
            }
            return res;
        }

        protected int GetMaxPageCount()
        {
            var path = "/configuration/sqlite/dbconfig/maxpagecount";
            var res = -1;
            var node = xml.SelectSingleNode(path);
            if (node != null)
            {
                var temp = node.Value;
                if (!string.IsNullOrEmpty(temp))
                {
                    int.TryParse(temp, out res);
                }
            }
            return res;
        }

        protected int GetPageSize()
        {
            var path = "/configuration/sqlite/dbconfig/pagesize";
            var res = -1;
            var node = xml.SelectSingleNode(path);
            if (node != null)
            {
                var temp = node.Value;
                if (!string.IsNullOrEmpty(temp))
                {
                    int.TryParse(temp, out res);
                }
            }
            return res;
        }

        protected bool GetPooling()
        {
            var path = "/configuration/sqlite/dbconfig/pooling";
            var res = false;
            var node = xml.SelectSingleNode(path);
            if (node != null)
            {
                var temp = node.Value;
                if (!string.IsNullOrEmpty(temp) && temp.ToLower().CompareTo("true") == 0)
                {
                    res = true;
                }
            }
            return res;
        }

        protected string GetPwd()
        {
            var path = "/configuration/sqlite/dbconfig/password";
            var res = "";
            var node = xml.SelectSingleNode(path);
            if (node != null)
            {
                var temp = node.Value;
                if (!string.IsNullOrEmpty(temp))
                {
                    res = temp;
                }
            }
            return res;
        }

        protected bool GetUseUTF16Encoding()
        {
            var path = "/configuration/sqlite/dbconfig/useutf16encoding";
            var res = false;
            var node = xml.SelectSingleNode(path);
            if (node != null)
            {
                var temp = node.Value;
                if (!string.IsNullOrEmpty(temp) && temp.ToLower().CompareTo("true") == 0)
                {
                    res = true;
                }
            }
            return res;
        }

        protected int GetVersion()
        {
            var path = "/configuration/sqlite/dbconfig/version";
            var res = -1;
            var node = xml.SelectSingleNode(path);
            if (node != null)
            {
                var temp = node.Value;
                if (!string.IsNullOrEmpty(temp))
                {
                    int.TryParse(temp, out res);
                }
            }
            return res;
        }
    }
}
